package com.hunliji.monitor.web.facade.impl;

import com.hunliji.common.exception.WarnException;
import com.hunliji.common.response.PageData;
import com.hunliji.monitor.service.api.BusinessChangeOrderAffirmService;
import com.hunliji.monitor.service.api.BusinessChangeOrderService;
import com.hunliji.monitor.service.api.BusinessTableRecordService;
import com.hunliji.monitor.service.api.model.bo.BusinessChangeAffirmOrderBO;
import com.hunliji.monitor.service.api.model.bo.BusinessChangeOrderBO;
import com.hunliji.monitor.service.api.model.bo.BusinessTableRecordBO;
import com.hunliji.monitor.service.api.model.param.*;
import com.hunliji.monitor.share.enums.order.AffirmStatusEnum;
import com.hunliji.monitor.share.enums.order.ChangeOrderStatusEnum;
import com.hunliji.monitor.share.utils.PageDataUtil;
import com.hunliji.monitor.web.facade.TableAffirmOrderFacade;
import com.hunliji.monitor.web.model.vo.AffirmOrderVO;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 确认单
 * @author wuchen
 */
@Service
public class TableAffirmOrderFacadeImpl implements TableAffirmOrderFacade {
    @Resource
    private BusinessChangeOrderAffirmService changeOrderAffirmService;
    @Resource
    private BusinessChangeOrderService changeOrderService;
    @Resource
    private BusinessTableRecordService tableRecordService;
    @Override
    public PageData<AffirmOrderVO> queryPage(QueryAffirmOrderParam queryAffirmOrderParam) {
        QueryChangeAffirmOrderParam queryChangeAffirmOrderParam = new QueryChangeAffirmOrderParam();
        queryChangeAffirmOrderParam.setAffirmStatus(queryAffirmOrderParam.getAffirmStatus());
        queryChangeAffirmOrderParam.setUserId(queryAffirmOrderParam.getUserId());
        queryChangeAffirmOrderParam.setPageNum(queryAffirmOrderParam.getPageNum());
        queryChangeAffirmOrderParam.setPageSize(queryAffirmOrderParam.getPageSize());
        PageData<BusinessChangeAffirmOrderBO> pageData =  changeOrderAffirmService.queryPage(queryChangeAffirmOrderParam);
        List<BusinessChangeAffirmOrderBO> changeAffirmOrderBOList = pageData.getList();
        if(CollectionUtils.isEmpty(changeAffirmOrderBOList)){
            return PageDataUtil.getEmptyData();
        }
        //获取变更单--->转map
        List<Long> changeOrderIdList = changeAffirmOrderBOList.stream().map(BusinessChangeAffirmOrderBO::getChangeOrderId).collect(Collectors.toList());
        QueryTableChangeOrderParam queryTableChangeOrderParam = new QueryTableChangeOrderParam();
        queryTableChangeOrderParam.setIds(changeOrderIdList);
        List<BusinessChangeOrderBO> changeOrderBOList = changeOrderService.query(queryTableChangeOrderParam);
        Map<Long,BusinessChangeOrderBO> changeOrderBOMap = changeOrderBOList.stream().collect(Collectors.toMap(BusinessChangeOrderBO::getId,s->s));
        //获取表记录，转map
        List<Long> tableRecordIdList = changeOrderBOList.stream().map(BusinessChangeOrderBO::getLinkId).collect(Collectors.toList());
        QueryBusinessTableRecordParam queryBusinessTableRecordParam = new QueryBusinessTableRecordParam();
        queryBusinessTableRecordParam.setIds(tableRecordIdList);
        List<BusinessTableRecordBO> tableRecordBOList =  tableRecordService.query(queryBusinessTableRecordParam);
        Map<Long,BusinessTableRecordBO> tableRecordBOMap = tableRecordBOList.stream().collect(Collectors.toMap(BusinessTableRecordBO::getId,s->s));
        //进行数据的转换
        List<AffirmOrderVO> affirmOrderVOList = new ArrayList<>();
        for (BusinessChangeAffirmOrderBO affirmOrderBO:changeAffirmOrderBOList){
            AffirmOrderVO affirmOrderVO = new AffirmOrderVO();
            affirmOrderVO.setId(affirmOrderBO.getId());
            affirmOrderVO.setAffirmStatus(affirmOrderBO.getAffirmStatus());
            BusinessChangeOrderBO changeOrderBO = changeOrderBOMap.get(affirmOrderBO.getChangeOrderId());
            if(Objects.nonNull(changeOrderBO)){
                affirmOrderVO.setDescribes(changeOrderBO.getDescribes());
                affirmOrderVO.setExecuteInfo(changeOrderBO.getExecuteInfo());
                BusinessTableRecordBO tableRecordBO = tableRecordBOMap.get(changeOrderBO.getLinkId());
                if(Objects.nonNull(tableRecordBO)){
                    affirmOrderVO.setDbName(tableRecordBO.getDatabaseName());
                    affirmOrderVO.setTableName(tableRecordBO.getTableName());
                }
            }
            affirmOrderVOList.add(affirmOrderVO);

        }
        return PageDataUtil.getPageData(pageData.getTotalCount(),affirmOrderVOList);
    }

    @Override
    public AffirmOrderVO queryById(Long id,Long userId) {
        BusinessChangeAffirmOrderBO affirmOrderBO = changeOrderAffirmService.queryById(id);
        if(Objects.isNull(affirmOrderBO)){
            throw new WarnException("无法查询到该确认单");
        }
        if(Objects.nonNull(userId) && (!userId.equals(affirmOrderBO.getUserId()))){
            throw new WarnException("可以查询到变更单，但是你没有权限查看");
        }
        //查询变更单
        BusinessChangeOrderBO changeOrderBO = changeOrderService.queryById(affirmOrderBO.getChangeOrderId());
        if(Objects.isNull(changeOrderBO)){
            throw new WarnException("数据异常，无法查询到对应变更单记录，可能是变更单已经被删除");
        }
        //查询表
        BusinessTableRecordBO tableRecordBO = tableRecordService.queryById(changeOrderBO.getLinkId());
        if(Objects.isNull(tableRecordBO)){
            throw new WarnException("数据异常，无法查询到对应表记录，可能是表已经被删除");
        }
        AffirmOrderVO affirmOrderVO = new AffirmOrderVO();
        affirmOrderVO.setId(affirmOrderBO.getId());
        affirmOrderVO.setAffirmStatus(affirmOrderBO.getAffirmStatus());
        if(Objects.nonNull(changeOrderBO)){
            affirmOrderVO.setDescribes(changeOrderBO.getDescribes());
            affirmOrderVO.setExecuteInfo(changeOrderBO.getExecuteInfo());
            if(Objects.nonNull(tableRecordBO)){
                affirmOrderVO.setDbName(tableRecordBO.getDatabaseName());
                affirmOrderVO.setTableName(tableRecordBO.getTableName());
            }
        }

        return affirmOrderVO;
    }

    /**
     * 对确认单进行基本状态的校验
     * @param affirmOrderBO
     */
    private void operateBasicCheck(BusinessChangeAffirmOrderBO affirmOrderBO){
        if(Objects.isNull(affirmOrderBO)){
            throw new WarnException("无法查询到对应的确认单");
        }
        //查询变更单的状态
        BusinessChangeOrderBO changeOrderBO =  changeOrderService.queryById(affirmOrderBO.getChangeOrderId());
        if(Objects.isNull(changeOrderBO)){
            throw new WarnException("无法查询到对应的变更单");
        }
        if(!ChangeOrderStatusEnum.AFFIRM.getCode().equals( changeOrderBO.getOrderStatus())){
            throw new WarnException("当前变更单状态不支持当前操作，请确认后重试");
        }
    }

    @Override
    @Transactional(rollbackFor = {Exception.class,RuntimeException.class},transactionManager = "mtTransactionManager")
    public void operateStatus(OperateAffirmOrderParam operateAffirmOrderParam,Long uerId) {
        BusinessChangeAffirmOrderBO affirmOrderBO = changeOrderAffirmService.queryById(operateAffirmOrderParam.getId());
        //基本状态校验
        operateBasicCheck(affirmOrderBO);
        if(!uerId.equals(affirmOrderBO.getUserId())){
            throw new WarnException("无权进行本操作");
        }
        //先变更状态
        affirmOrderBO.setAffirmStatus(operateAffirmOrderParam.getAffirmStatus());
        affirmOrderBO.setAffirmIdea(operateAffirmOrderParam.getAffirmIdea());
        changeOrderAffirmService.update(affirmOrderBO);
        //检查是不是全部的单据都已经完成了,检查待确认的数量
        Long affirmingCount = queryCount(affirmOrderBO.getChangeOrderId(),AffirmStatusEnum.AFFIRM_ING);
        if(affirmingCount == 0){
            BusinessChangeOrderBO changeOrderBO =  changeOrderService.queryById(affirmOrderBO.getChangeOrderId());
            changeOrderBO.setOrderStatus(ChangeOrderStatusEnum.AFFIRM_COMPLETE.getCode());
            changeOrderService.update(changeOrderBO);
        }
    }

    /**
     * 数量查询
     * @param changeOrderId
     * @param affirmStatus
     * @return
     */
    private Long queryCount(Long changeOrderId,AffirmStatusEnum affirmStatus){
        QueryOrderAffirmCountGroupParam queryOrderAffirmCountGroupParam = new QueryOrderAffirmCountGroupParam();
        queryOrderAffirmCountGroupParam.setChangeOrderIdList(Arrays.asList(changeOrderId));
        queryOrderAffirmCountGroupParam.setAffirmStatus(affirmStatus.getCode());
        Map<Long,Long> countGroupByChangeOrderIdMap = changeOrderAffirmService.queryGroupCount(queryOrderAffirmCountGroupParam);
        if(Objects.isNull(countGroupByChangeOrderIdMap.get(changeOrderId))){
            return 0L;
        }
        return countGroupByChangeOrderIdMap.get(changeOrderId);
    }
}
